{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# C++的封装"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 封装"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.1 封装属性和行为"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 封装是C++面向对象三大特性之一。\n",
    "\n",
    "② 封装的意义一：\n",
    "\n",
    "1. 将属性和行为作为一个整体，表现生活中的事物。\n",
    "2. 将属性和行为加以权限控制。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "\n",
    "const double PI = 3.14;\n",
    "\n",
    "//设计一个圆类，求圆的周长\n",
    "//圆求周长的公式： 2 * PI * 半径\n",
    "\n",
    "//class 代表设计一个类，类后面紧跟着的就是类名称\n",
    "class Circle\n",
    "{\n",
    "    //访问权限\n",
    "    //公共权限\n",
    "    public:   //是冒号，不是分号\n",
    "\n",
    "    //属性\n",
    "    //半径\n",
    "    int m_r;\n",
    "\n",
    "    //行为\n",
    "    //获取圆的周长\n",
    "    double calculateZC()\n",
    "    {\n",
    "        return 2 * PI * m_r;\n",
    "    }\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    //通过圆类 创建具体的圆(对象)\n",
    "    //实例化 （通过一个类 创建一个对象的过程）\n",
    "    Circle c1;\n",
    "    //给圆对象  的属性进行赋值\n",
    "    c1.m_r = 10;\n",
    "\n",
    "    // 2 * PI * 10 = 62.8\n",
    "    cout << \"圆的周长为：\" << c1.calculateZC() << endl;\n",
    "\n",
    "    system(\"pause\");\n",
    "    \n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：  \n",
    " - 圆的周长为：62.8"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 封装权限"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 类在设计时，可以把属性和行为放在不同的权限下，加以控制。\n",
    "\n",
    "② 封装的意义二：\n",
    "\n",
    "1. public 公共权限\n",
    "2. protected 保护权限\n",
    "3. private 私有权限"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "\n",
    "//访问权限\n",
    "//三种\n",
    "//公共权限 public     类内可以访问成员 类外可以访问成员\n",
    "//保护权限 protected  类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容\n",
    "//私有权限 private    类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容\n",
    "\n",
    "class Person\n",
    "{\n",
    "//公共权限\n",
    "public:   \n",
    "    string m_Name;  //姓名\n",
    "\n",
    "protected:\n",
    "    string m_Car;  //汽车\n",
    "\n",
    "private:\n",
    "    int m_Password; //银行卡密码\n",
    "\n",
    "public:\n",
    "    void func()\n",
    "    {\n",
    "        m_Name = \"李四\";\n",
    "        m_Car = \"奔驰\";  //保护权限内容，在类外访问不到\n",
    "        m_Password = 123;\n",
    "    }\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    //实例化具体对象\n",
    "    Person p1;\n",
    "    p1.m_Name = \"李四\";\n",
    "    p1.m_Car = \"奔驰\";  //保护权限内容，在类外访问不到\n",
    "    p1.m_Password = 123; //私有权限内容，在类外访问不到\n",
    "\n",
    "    p1.func();  //公共权限内容，在类可以访问\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 struct 和 class 区别"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 在C++中struct和class唯一的区别就在于默认的访问权限不同。\n",
    "\n",
    "② 区别：\n",
    "\n",
    "1. struct 默认权限为公共。\n",
    "2. class 默认权限为私有。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "\n",
    "//访问权限\n",
    "//三种\n",
    "//公共权限 public     类内可以访问成员 类外可以访问成员\n",
    "//保护权限 protected  类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容\n",
    "//私有权限 private    类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容\n",
    "\n",
    "class C1\n",
    "{\n",
    "    int m_A;  // 默认权限是私有\n",
    "};\n",
    "\n",
    "struct C2\n",
    "{\n",
    "    int m_A; //默认权限 是公共\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    //struct 和 class 区别\n",
    "    //struct 默认权限是 公共 public\n",
    "    //class  默认权限是 私有 private\n",
    "    C1 c1;\n",
    "    c1.m_A = 100;  //私有权限，不能访问\n",
    "\n",
    "    C2 c2;\n",
    "    c2.m_A = 100;   //公共权限，可以访问\n",
    "\n",
    "    system(\"pause\");\n",
    "    \n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4 成员属性设置为私有"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "① 优点1：将所有成员属性设置为私有，可以自己控制读写权限。\n",
    "\n",
    "② 优点2：可以通过写权限，检测数据的有效性。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "#include <string>\n",
    "\n",
    "//成员属性设置为私有\n",
    "//1、可以自己控制读写权限\n",
    "//2、对于写可以检测数据的有效性\n",
    "\n",
    "class Person\n",
    "{\n",
    "public:\n",
    "    //设置姓名\n",
    "    void setName(string name)\n",
    "    {\n",
    "        m_Name = name;\n",
    "    }\n",
    "    //获取姓名\n",
    "    string getName()\n",
    "    {\n",
    "        return m_Name;\n",
    "    }\n",
    "\n",
    "    //获取年龄\n",
    "    int getAge()\n",
    "    {\n",
    "        m_Age = 0;  //初始化为0岁\n",
    "        return m_Age;\n",
    "    }\n",
    "\n",
    "    void setLover(string lover)\n",
    "    {\n",
    "        m_Lover = lover;\n",
    "    }\n",
    "\n",
    "private:\n",
    "    //姓名 可读可写\n",
    "    string m_Name;\n",
    "    //年龄 只读\n",
    "    int m_Age;\n",
    "    //情人 只写\n",
    "    string m_Lover;\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    Person p;\n",
    "    p.setName(\"张三\");\n",
    "\n",
    "    cout << \"姓名为：\" << p.getName() << endl;\n",
    "\n",
    "    cout << \"年龄为：\" << p.getName() << endl;\n",
    "\n",
    "    //p.m_Age = 18;  //私有权限，不可以改\n",
    "    p.getAge();\n",
    "    cout << \"姓名为：\" << p.getAge() << endl;\n",
    "\n",
    "    p.setLover(\"小李\");\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：  \n",
    " - 姓名为：张三  \n",
    " - 年龄为：0  \n",
    " - 请按任意键继续. . ."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "#include <string>\n",
    "\n",
    "//成员属性设置为私有\n",
    "//1、可以自己控制读写权限\n",
    "//2、对于写可以检测数据的有效性\n",
    "\n",
    "class Person\n",
    "{\n",
    "public:\n",
    "    //设置姓名\n",
    "    void setName(string name)\n",
    "    {\n",
    "        m_Name = name;\n",
    "    }\n",
    "    //获取姓名\n",
    "    string getName()\n",
    "    {\n",
    "        return m_Name;\n",
    "    }\n",
    "\n",
    "    //获取年龄 可读可写 \n",
    "    int getAge()\n",
    "    {\n",
    "        return m_Age;\n",
    "    }\n",
    "\n",
    "    //设置年龄 如果想修改（年龄的范围必须是0~150之间）\n",
    "    void setAge(int age)\n",
    "    {\n",
    "        if (age < 0 || age>150)\n",
    "        {\n",
    "            m_Age = 0; //强制改为0\n",
    "            cout << \"你这个老妖精！\" << endl;\n",
    "            return; //强制退出\n",
    "        }\n",
    "        m_Age = age;\n",
    "    }\n",
    "\n",
    "    void setLover(string lover)\n",
    "    {\n",
    "        m_Lover = lover;\n",
    "    }\n",
    "\n",
    "private:\n",
    "    //姓名 可读可写\n",
    "    string m_Name;\n",
    "    //年龄 只读\n",
    "    int m_Age;\n",
    "    //情人 只写\n",
    "    string m_Lover;\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    Person p;\n",
    "    p.setName(\"张三\");\n",
    "\n",
    "    cout << \"姓名为：\" << p.getName() << endl;\n",
    "\n",
    "\n",
    "    //p.m_Age = 18;  //私有权限，不可以类外改\n",
    "    p.setAge(1000);  \n",
    "    cout << \"年龄为：\" << p.getAge() << endl;\n",
    "\n",
    "    //设置情人为苍井女士\n",
    "    p.setLover(\"小李\");  //有这个函数可以设置\n",
    "    //cout << \"情人为：\" << p.getLover() << endl;  //没有这个函数，不能获得\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：  \n",
    " - 姓名为：张三  \n",
    " - 你这个老妖精！  \n",
    " - 年龄为：0  \n",
    " - 请按任意键继续. . ."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.5 设计学生类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "案例描述：设计一个学生类，属性有姓名和学号，可以给姓名和学号赋值，可以显示学生的姓名和学号。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "#include<string>\n",
    "\n",
    "//设计学生类\n",
    "class Student\n",
    "{\n",
    "public: //公共权限\n",
    "\n",
    "    //类中的属性和行为 我们统一称为成员\n",
    "    // 属性 成员属性 成员变量\n",
    "    // 行为 成员函数 成员方法\n",
    "    \n",
    "    //属性\n",
    "    string m_Name;  //姓名\n",
    "    int m_Id;  //学号\n",
    "\n",
    "    //行为\n",
    "    //显示姓名和学号\n",
    "    void showStudent()\n",
    "    {\n",
    "        cout << \"姓名：\" << m_Name << \" 学号：\" << m_Id << endl;\n",
    "    }\n",
    "\n",
    "    //给姓名赋值的行为\n",
    "    void setName(string name)\n",
    "    {\n",
    "        m_Name = name;\n",
    "    }\n",
    "};\n",
    "\n",
    "int main()\n",
    "{\n",
    "    //创建一个具体学生  实例化对象\n",
    "    Student s1;\n",
    "    //给s1对象 进行属性赋值操作\n",
    "    s1.m_Name = \"张三\";\n",
    "    s1.m_Id = 1;\n",
    "\n",
    "    s1.showStudent();\n",
    "\n",
    "    Student s2;\n",
    "    s2.m_Name = \"李四\";\n",
    "    s2.m_Id = 2;\n",
    "    s2.showStudent();\n",
    "\n",
    "    Student s3;\n",
    "    s3.setName(\"王五\");\n",
    "    s3.m_Id = 3;\n",
    "    s3.showStudent();\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：  \n",
    " - 姓名：张三 学号：1  \n",
    " - 姓名：李四 学号：2  \n",
    " - 姓名：王五 学号：3  \n",
    " - 请按任意键继续. . ."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.6 设计立方体类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "案例描述：设计立方体类(Cube)，求出立方体的面积和体积，分别用全局函数和成员函数判断两个立方体是否相等。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#include <iostream>\n",
    "using namespace std;\n",
    "\n",
    "//立方体类设计\n",
    "//1、创建立方体类\n",
    "//2、设计属性\n",
    "//3、获取立方体面积和体积\n",
    "//4、分别利用全局函数和成员函数 判断两个立方体是否相等\n",
    "\n",
    "class Cube\n",
    "{\n",
    "public:\n",
    "    //设置长\n",
    "    void setL(int l)\n",
    "    {\n",
    "        m_L = l;\n",
    "    }\n",
    "\n",
    "    //获取长\n",
    "    int getL()\n",
    "    {\n",
    "        return m_L;\n",
    "    }\n",
    "\n",
    "    //设置宽\n",
    "    void setW(int w)\n",
    "    {\n",
    "        m_W = w;\n",
    "    }\n",
    "\n",
    "    //获取宽\n",
    "    int getW()\n",
    "    {\n",
    "        return m_W;\n",
    "    }\n",
    "\n",
    "    //设置高\n",
    "    void setH(int h)\n",
    "    {\n",
    "        m_H = h;\n",
    "    }\n",
    "\n",
    "    //获取高\n",
    "    int getH()\n",
    "    {\n",
    "        return m_H;\n",
    "    }\n",
    "\n",
    "    //获取立方体面积\n",
    "    int calculateS()\n",
    "    {\n",
    "        return 2 * m_L * m_W + 2 * m_W * m_H + 2 * m_L * m_H;\n",
    "    }\n",
    "\n",
    "    //获取立方体体积\n",
    "    int calculateV()\n",
    "    {\n",
    "        return m_L * m_W * m_H;\n",
    "    }\n",
    "\n",
    "    //利用成员函数判断两个立方体是否相等\n",
    "    bool isSameByClass(Cube c) //成员函数只需要传入一个类为参数\n",
    "    {\n",
    "        if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH()) //类内可以访问成员函数：m_L、m_W、m_H\n",
    "        {\n",
    "            return true;\n",
    "        }\n",
    "        else\n",
    "        {\n",
    "            return false;\n",
    "        }\n",
    "    }\n",
    "\n",
    "\n",
    "private:\n",
    "    int m_L; //长\n",
    "    int m_W; //宽\n",
    "    int m_H; //高\n",
    "};\n",
    "\n",
    "//利用全局函数判断，两个立方体是否相等\n",
    "bool isSame(Cube c1, Cube c2) //值传递会拷贝一份数据，通过引用传递用原始数据，不会拷贝数据\n",
    "{\n",
    "    if (c1.getL() == c2.getL() && c1.getW() == c2.getW()\n",
    "        && c1.getH() == c2.getH())\n",
    "    {\n",
    "        return true;\n",
    "    }\n",
    "    else\n",
    "    {\n",
    "        return false;\n",
    "    }\n",
    "}\n",
    "\n",
    "int main()\n",
    "{\n",
    "    //创建立方体对象\n",
    "    Cube c1;\n",
    "    c1.setL(10);\n",
    "    c1.setW(10);\n",
    "    c1.setH(10);\n",
    "\n",
    "    cout << \"c1的面积为：\" << c1.calculateS() << endl; \n",
    "    cout << \"c1的体积为：\" << c1.calculateV() << endl; \n",
    "\n",
    "    Cube c2;\n",
    "    c2.setL(10);\n",
    "    c2.setW(10);\n",
    "    c2.setH(11);\n",
    "\n",
    "    bool ret = isSame(c1, c2);\n",
    "    if (ret)\n",
    "    {\n",
    "        cout << \"利用全局函数判断：c1和c2是相等的\" << endl;\n",
    "    }\n",
    "    else\n",
    "    {\n",
    "        cout << \"利用全局函数判断：c1和c2是不相等的\" << endl;\n",
    "    }\n",
    "\n",
    "\n",
    "    //利用成员函数判断\n",
    "    ret = c1.isSameByClass(c2);\n",
    "    if (ret)\n",
    "    {\n",
    "        cout << \"利用成员函数判断：c1和c2是相等的\" << endl;\n",
    "    }\n",
    "    else\n",
    "    {\n",
    "        cout << \"利用成员函数判断：c1和c2是不相等的\" << endl;\n",
    "    }\n",
    "\n",
    "    system(\"pause\");\n",
    "\n",
    "    return 0;\n",
    "\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行结果：  \n",
    " - c1的面积为：600  \n",
    " - c1的体积为：1000  \n",
    " - 利用全局函数判断：c1和c2是不相等的  \n",
    " - 利用成员函数判断：c1和c2是不相等的  \n",
    " - 请按任意键继续. . ."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.6.3",
   "language": "python",
   "name": "python3.6.3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": false,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
